package weaver.tools.util;

import org.apache.commons.lang.StringUtils;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import weaver.general.BaseBean;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

/**
 * @Title: Ecology9
 * @Company: 泛微软件
 * @author: weaver.Dusongsong
 * @version: 1.0
 * @CreateDate: 2021-09-15
 * @Description: 文件工具类
 * @ModifyLog:
 **/

public class FileUtil {
    //将文件转成base64 字符串
    public static String encodeBase64File(String path) throws Exception {
        File file = new File(path);
        FileInputStream inputFile = new FileInputStream(file);
        byte[] buffer = new byte[(int) file.length()];
        inputFile.read(buffer);
        inputFile.close();
        return new BASE64Encoder().encode(buffer);
    }

    //将base64字符解码保存文件
    public static void decoderBase64File(String base64Code, String targetPath) throws Exception {
        byte[] buffer = new BASE64Decoder().decodeBuffer(base64Code);
        FileOutputStream out = new FileOutputStream(targetPath);
        out.write(buffer);
        out.close();
    }

    //将base64字符保存文本文件
    public static void toFile(String base64Code, String targetPath) throws Exception {
        byte[] buffer = base64Code.getBytes();
        FileOutputStream out = new FileOutputStream(targetPath);
        out.write(buffer);
        out.close();
    }

    //十六进制转成文件
    public static void hexToFile(String hex, String filePath) {
        StringBuilder sb = new StringBuilder();
        sb.append( hex );
        saveToFile( sb.toString().toUpperCase(), filePath );
    }

    //hex 转为文件
    public static void saveToFile(String src, String output) {
        if (src == null || src.length() == 0) {
            return;
        }
        try {
            File file = new File( output );
            FileOutputStream out = new FileOutputStream( file );
            byte[] bytes = src.getBytes();
            for (int i = 0; i < bytes.length; i += 2) {
                out.write( charToInt( bytes[i] ) * 16 + charToInt( bytes[i + 1] ) );
            }
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static int charToInt(byte ch) {
        int val = 0;
        if (ch >= 0x30 && ch <= 0x39) {
            val = ch - 0x30;
        } else if (ch >= 0x41 && ch <= 0x46) {
            val = ch - 0x41 + 10;
        }
        return val;
    }

    //创建目录
    public static boolean createDir(String destDirName) {
        File dir = new File( destDirName );
        if (dir.exists()) {
            File[] files = dir.listFiles();
            if (files.length >= 1) {
                for (File fileToDel : files) {
                    fileToDel.delete();
                }

            }
            return false;
        }
        if (!destDirName.endsWith( File.separator )) {
            destDirName = destDirName + File.separator;
        }
        //创建目录
        if (dir.mkdirs()) {
            return true;
        } else {
            return false;
        }
    }

    //创建文件
    //（1）判断文件是否已经存在 （2）判断是不是目录（4）判断目录是否存在，不存在则创建（5）创建目标文件
    public static boolean createNewFile(String destFileName) {
        File file = new File( destFileName );
        if (file.exists()) {
            return false;
        }
        if (destFileName.endsWith( File.separator )) {
            return false;
        }
        //判断目标文件所在的目录是否存在
        if (!file.getParentFile().exists()) {
            //如果目标文件所在的目录不存在，则创建父目录
            if (!file.getParentFile().mkdirs()) {
                return false;
            }
        }
        //创建目标文件
        try {

            if (file.createNewFile()) {
                return true;
            } else {
                return false;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    //下载图片
    public static void downloadPicture(String srcUrl,String destPath) {
        URL url = null;
        try {
            //unZip(file,destPath);
            url = new URL(srcUrl);
            DataInputStream dataInputStream = new DataInputStream(url.openStream());

            FileOutputStream fileOutputStream = new FileOutputStream(new File(destPath));
            ByteArrayOutputStream output = new ByteArrayOutputStream();

            byte[] buffer = new byte[1024];
            int length;

            while ((length = dataInputStream.read(buffer)) > 0) {
                output.write(buffer, 0, length);
            }
            fileOutputStream.write(output.toByteArray());
            dataInputStream.close();
            fileOutputStream.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //源文件压缩zip格式
    public static File doZip(String sourceDir, String zipFilePath, int needDelSource) {
        weaver.general.BaseBean baseBean = new weaver.general.BaseBean();
        File file = new File( sourceDir );
        File zipFile = new File( zipFilePath );
        ZipOutputStream zos = null;
        OutputStream os = null;
        BufferedOutputStream bos = null;
        if (!file.exists()) {
            return null;
        }
        try {
            // 创建写出流操作
            os = new FileOutputStream( zipFile );
            bos = new BufferedOutputStream( os );
            zos = new ZipOutputStream( bos );
            String basePath = null;
            // 获取目录
            if (file.isDirectory()) {
                basePath = file.getPath();
            } else {
                basePath = file.getParent();
            }
            zipFile( file, basePath, zos );

        } catch (IOException ex) {
            ex.printStackTrace();
            baseBean.writeLog( "IO异常：" + ex.toString() );
        } finally {
            try {
                if (needDelSource == 1) {
                    delFolder( sourceDir );
                }
                if (zos != null) {
                    zos.closeEntry();
                    zos.close();
                }
                if (bos != null) {
                    bos.close();
                }
                if (os != null) {
                    os.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
                baseBean.writeLog( "IO异常：" + e.toString() );
            }
        }
        return zipFile;
    }

    //解压文件
    public static void unZip(String srcPath, String destDirPath) throws RuntimeException {
        File srcFile = new File(srcPath);
        long start = System.currentTimeMillis();
        if(!srcFile.exists()){
            throw new RuntimeException(srcFile.getPath() + "所指文件不存在");
        }
        //开始解压
        ZipFile zipFile = null;
        try{
            zipFile = new ZipFile(srcFile);
            Enumeration<?> entries = zipFile.entries();
            while (entries.hasMoreElements()){
                ZipEntry entry = (ZipEntry) entries.nextElement();
                System.out.println("解压" + entry.getName());
                // 如果是文件夹，就创建个文件夹
                if(entry.isDirectory()){
                    String dirPath = destDirPath + "/" + entry.getName();
                    File dir = new File(dirPath);
                    dir.mkdirs();
                }else {
                    // 如果是文件，就先创建一个文件，然后用io流把内容copy过去
                    File targetFile = new File(destDirPath + "/" + entry.getName());
                    // 保证这个文件的父文件夹必须要存在
                    if(!targetFile.getParentFile().exists()) {
                        targetFile.getParentFile().mkdirs();
                    }
                    targetFile.createNewFile();
                    // 将压缩文件内容写入到这个文件中
                    InputStream is = zipFile.getInputStream(entry);
                    FileOutputStream fos = new FileOutputStream(targetFile);
                    int len;
                    byte[] buf = new byte[1024];
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                    }
                    // 关流顺序，先打开的后关闭
                    fos.close();
                    is.close();
                }
            }
            long end = System.currentTimeMillis();
            System.out.println("解压完成，耗时：" + (end - start) +" ms");
        }catch (Exception e){
            throw new RuntimeException("unzip error from ZipUtils", e);
        }finally {
            if(zipFile !=null){
                try {
                    zipFile.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }
    //解压文件
    public static String unzip(String fileRealPath,String imagefilename){
        int count = -1;
        BaseBean bs=new BaseBean();
        String resulturl="";
        int index=fileRealPath.lastIndexOf(".");
        if(index>0){
            resulturl=fileRealPath.split("\\.")[0]+"."+imagefilename.split("\\.")[1];
        }

        BufferedOutputStream bos = null;
        java.util.zip.ZipEntry entry = null;
        FileInputStream fis;
        try {
            fis = new FileInputStream(fileRealPath);
            ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
            while ((entry = zis.getNextEntry()) != null) {
                byte[] data = new byte[2048];

                File f = new File(resulturl);

                f.createNewFile();

                FileOutputStream fos = new FileOutputStream(f);
                bos = new BufferedOutputStream(fos, 2048);

                while ((count = zis.read(data, 0, 2048)) != -1) {
                    bos.write(data, 0, count);
                }

                bos.flush();
                bos.close();
            }

            zis.close();


        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return resulturl;

    }

    private static void zipFile(File source, String basePath, ZipOutputStream zos) {
        BaseBean baseBean = new BaseBean();
        File[] files = null;
        if (source.isDirectory()) {
            files = source.listFiles();
        } else {
            files = new File[1];
            files[0] = source;
        }
        InputStream is = null;
        String pathName;
        byte[] buf = new byte[1024];
        int length = 0;
        try {
            for (File file : files) {
                if (file.isDirectory()) {
                    pathName = file.getPath().substring( basePath.length() + 1 ) + "/";
                    zos.putNextEntry( new ZipEntry( pathName ) );
                    zipFile( file, basePath, zos );
                } else {
                    pathName = file.getPath().substring( basePath.length() + 1 );
                    is = new FileInputStream( file );
                    BufferedInputStream bis = new BufferedInputStream( is );
                    zos.putNextEntry( new ZipEntry( pathName ) );
                    while ((length = bis.read( buf )) > 0) {
                        zos.write( buf, 0, length );
                    }
                    if (bis != null) {
                        bis.close();
                    }
                }
            }
        } catch (IOException ex) {
            ex.printStackTrace();
            baseBean.writeLog( "IO异常：" + ex.toString() );
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    baseBean.writeLog( "IO异常：" + e.toString() );
                }
            }
        }
    }

    //删除路径下文件夹
    public static boolean delFolder(String folderPath) {
        weaver.general.BaseBean baseBean = new weaver.general.BaseBean();
        if (StringUtils.isEmpty( folderPath )) {
            return Boolean.FALSE;
        }
        try {
            delAllFile( folderPath );  //删除完里面所有内容
            File myFilePath = new File( folderPath );
            if (myFilePath.exists()) {
                boolean result = myFilePath.delete();  //删除空文件夹
                //System.out.println( "---------------delete folder ------folderPath:"+folderPath);
                return result;
            }
        } catch (Exception e) {
            baseBean.writeLog( "删除文件夹操作出错" );
            e.printStackTrace();
            baseBean.writeLog( e.toString() );
        }
        return Boolean.FALSE;
    }

    //删除路径下所有文件
    public static void delAllFile(String path) {
        File file = new File( path );
        if (!file.exists()) {
            return;
        }
        if (!file.isDirectory()) {
            return;
        }
        String[] tempList = file.list();
        File temp = null;
        for (int i = 0; i < tempList.length; i++) {
            if (path.endsWith( File.separator )) {
                temp = new File( path + tempList[i] );
            } else {
                temp = new File( path + File.separator + tempList[i] );
            }
            if (temp.isFile()) {
                if (temp.exists()) {
                    temp.delete();
                }
            }
            if (temp.isDirectory()) {
                delAllFile( path + File.separator + tempList[i] );//先删除文件夹里面的文件
                delFolder( path + File.separator + tempList[i] );//再删除空文件夹
            }
        }

    }

}
